include(FindPkgConfig)
include(FindDoxygen)
include(GNUInstallDirs)

if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE Release)
endif()

#assuming build platform == target
set(PLATFORM 32)
if(WIN32)
    if(CMAKE_CL_64)
        set(PLATFORM 64)
    endif(CMAKE_CL_64)
else(WIN32)
    if(${CMAKE_SIZEOF_VOID_P} EQUAL 8)
        set(PLATFORM 64)
    endif()
endif(WIN32)

message(STATUS "CMake: version ${CMAKE_VERSION}")
message(STATUS "Target platform: ${CMAKE_SYSTEM_NAME} ${PLATFORM}-bit")
message(STATUS "C++ Compiler: ${CMAKE_CXX_COMPILER_ID} with version ${CMAKE_CXX_COMPILER_VERSION}")
message(STATUS "C Compiler: ${CMAKE_C_COMPILER_ID} with version ${CMAKE_C_COMPILER_VERSION}")
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
message(STATUS "Environment: TANGO_HOST=$ENV{TANGO_HOST}")

if(NOT TANGO_DEVICE_SERVER_PATH)
    #TODO windows
    set(TANGO_DEVICE_SERVER_PATH ${CMAKE_INSTALL_FULL_BINDIR})
endif()

if(CPPZMQ_BASE)
    message("Using CPPZMQ_BASE=${CPPZMQ_BASE}")
    include_directories(${CPPZMQ_BASE}/include)
endif(CPPZMQ_BASE)

if(IDL_BASE)
    message("Using IDL_BASEIDL_BASE=${IDL_BASE}")
    set(IDL_PKG_INCLUDE_DIRS ${IDL_BASE}/include)
else(IDL_BASE)
    pkg_search_module(IDL_PKG REQUIRED tangoidl)
endif(IDL_BASE)

if(OMNI_BASE)
    message("Using OMNI_BASE=${OMNI_BASE}")
    set(OMNIORB_PKG_INCLUDE_DIRS ${OMNI_BASE}/include)
    if(WIN32)
        set(OMNIIDL_PATH ${OMNI_BASE}/bin/x86_win32/)
        link_directories(${OMNI_BASE}/lib/x86_win32/)
        include_directories($ENV{OMNI_BASE}/include)
        if (CMAKE_BUILD_TYPE STREQUAL "Debug")
            set(OMNIORB_PKG_LIBRARIES_DYN "omniORB4_rtd.lib;omniDynamic4_rtd.lib;omnithread_rtd.lib;COS4_rtd.lib")
            set(OMNIORB_PKG_LIBRARIES_STA "omniORB4d.lib;omniDynamic4d.lib;omnithreadd.lib;COS4d.lib")
        else()
            set(OMNIORB_PKG_LIBRARIES_DYN "omniORB4_rt.lib;omniDynamic4_rt.lib;omnithread_rt.lib;COS4_rt.lib")
            set(OMNIORB_PKG_LIBRARIES_STA "omniORB4.lib;omniDynamic4.lib;omnithread.lib;COS4.lib")
        endif()
    else(WIN32)
        set(OMNIIDL_PATH ${OMNI_BASE}/bin/)
        include_directories(${OMNI_BASE}/include)
        link_directories(${OMNI_BASE}/lib)
        set(OMNIORB_PKG_LIBRARIES "-lomniORB4 -lomnithread -lCOS4 -lomniDynamic4")
    endif(WIN32)
else(OMNI_BASE)
    #CORBA
    pkg_search_module(OMNIORB_PKG REQUIRED omniORB4)
    #COS
    pkg_search_module(OMNICOS_PKG REQUIRED omniCOS4)
    #dynamic CORBA
    pkg_search_module(OMNIDYN_PKG REQUIRED omniDynamic4)
    if(NOT OMNIORB_PKG_FOUND)
        message(FATAL_ERROR "omniORB4 library is required for Tango")
    endif()
endif(OMNI_BASE)

if(ZMQ_BASE)
    message("Using ZMQ_BASE=${ZMQ_BASE}")
    set(ZMQ_PKG_INCLUDE_DIRS ${ZMQ_BASE}/include)
    if (WIN32)
        link_directories(${ZMQ_BASE}/lib/Debug)
        link_directories(${ZMQ_BASE}/lib/Release)
        link_directories(${ZMQ_BASE}/bin/Debug)
        link_directories(${ZMQ_BASE}/bin/Release)
        if(MSVC90)
            if(CMAKE_BUILD_TYPE STREQUAL "Debug")
                set(ZMQ_PKG_LIBRARIES_STA "libzmq-v90-mt-sgd-4_0_5.lib")
                set(ZMQ_PKG_LIBRARIES_DYN "libzmq-v90-mt-gd-4_0_5.lib")
            else(CMAKE_BUILD_TYPE STREQUAL "Debug")
                set(ZMQ_PKG_LIBRARIES_STA "libzmq-v90-mt-s-4_0_5.lib")
                set(ZMQ_PKG_LIBRARIES_DYN "libzmq-v90-mt-4_0_5.lib")
            endif(CMAKE_BUILD_TYPE STREQUAL "Debug")
        endif(MSVC90)
        if(MSVC10)
            if(CMAKE_BUILD_TYPE STREQUAL "Debug")
                set(ZMQ_PKG_LIBRARIES_STA "libzmq-v100-mt-sgd-4_0_5.lib")
                set(ZMQ_PKG_LIBRARIES_DYN "libzmq-v100-mt-gd-4_0_5.lib")
            else(CMAKE_BUILD_TYPE STREQUAL "Debug")
                set(ZMQ_PKG_LIBRARIES_STA "libzmq-v100-mt-s-4_0_5.lib")
                set(ZMQ_PKG_LIBRARIES_DYN "libzmq-v100-mt-4_0_5.lib")
            endif(CMAKE_BUILD_TYPE STREQUAL "Debug")
        endif(MSVC10)
        if(MSVC12)
            if(CMAKE_BUILD_TYPE STREQUAL "Debug")
                set(ZMQ_PKG_LIBRARIES_STA "libzmq-v120-mt-sgd-4_0_5.lib")
                set(ZMQ_PKG_LIBRARIES_DYN "libzmq-v120-mt-gd-4_0_5.lib")
            else(CMAKE_BUILD_TYPE STREQUAL "Debug")
                set(ZMQ_PKG_LIBRARIES_STA "libzmq-v120-mt-s-4_0_5.lib")
                set(ZMQ_PKG_LIBRARIES_DYN "libzmq-v120-mt-4_0_5.lib")
            endif(CMAKE_BUILD_TYPE STREQUAL "Debug")
        endif(MSVC12)
        if(CMAKE_VS_PLATFORM_TOOLSET STREQUAL "v140")
            if(CMAKE_BUILD_TYPE STREQUAL "Debug")
                set(ZMQ_PKG_LIBRARIES_STA "libzmq-v140-mt-sgd-4_0_5.lib")
                set(ZMQ_PKG_LIBRARIES_DYN "libzmq-v140-mt-gd-4_0_5.lib")
            else(CMAKE_BUILD_TYPE STREQUAL "Debug")
                set(ZMQ_PKG_LIBRARIES_STA "libzmq-v140-mt-s-4_0_5.lib")
                set(ZMQ_PKG_LIBRARIES_DYN "libzmq-v140-mt-4_0_5.lib")
            endif(CMAKE_BUILD_TYPE STREQUAL "Debug")
        endif(CMAKE_VS_PLATFORM_TOOLSET STREQUAL "v140")
        if(CMAKE_VS_PLATFORM_TOOLSET STREQUAL "v141")
            if(CMAKE_BUILD_TYPE STREQUAL "Debug")
                set(ZMQ_PKG_LIBRARIES_STA "libzmq-v141-mt-sgd-4_0_5.lib")
                set(ZMQ_PKG_LIBRARIES_DYN "libzmq-v141-mt-gd-4_0_5.lib")
            else(CMAKE_BUILD_TYPE STREQUAL "Debug")
                set(ZMQ_PKG_LIBRARIES_STA "libzmq-v141-mt-s-4_0_5.lib")
                set(ZMQ_PKG_LIBRARIES_DYN "libzmq-v141-mt-4_0_5.lib")
            endif(CMAKE_BUILD_TYPE STREQUAL "Debug")
        endif(CMAKE_VS_PLATFORM_TOOLSET STREQUAL "v141")
    else()
        set(ZMQ_PKG_LIBRARIES "-lzmq")
        link_directories(${ZMQ_BASE}/lib)
    endif()
    include_directories(${ZMQ_BASE}/include)
else(ZMQ_BASE)
    pkg_search_module(ZMQ_PKG REQUIRED libzmq)
    if(NOT ZMQ_PKG_FOUND)
        message(FATAL_ERROR "ZMQ library is required for Tango")
    endif()
endif(ZMQ_BASE)

if(PTHREAD_WIN)
    message("Using PTHREAD_WIN=${PTHREAD_WIN}")
    add_definitions(-DHAVE_PTHREAD_NP_H)
    set(PTHREAD_WIN_PKG_INCLUDE_DIRS ${PTHREAD_WIN}/include)

    if (CMAKE_BUILD_TYPE STREQUAL "Debug")
        set(PTHREAD_WIN_PKG_LIBRARIES_DYN "pthreadVC2d.lib")
        set(PTHREAD_WIN_PKG_LIBRARIES_STA "pthreadVC2-sd.lib")
    else()
        set(PTHREAD_WIN_PKG_LIBRARIES_DYN "pthreadVC2.lib")
        set(PTHREAD_WIN_PKG_LIBRARIES_STA "pthreadVC2-s.lib")
    endif()
endif(PTHREAD_WIN)

#####  Ensure zmq.hpp file is present #####
include(CheckIncludeFileCXX)
# set CMAKE_REQUIRED_INCLUDES to take the currently defined include directories into account when looking for zmq.hpp
get_property(CMAKE_REQUIRED_INCLUDES DIRECTORY PROPERTY INCLUDE_DIRECTORIES)
# Clear HAVE_ZMQ_HPP variable from the cache to force the check every time
# Thanks to this, the user do not have to clear the CMake cache himself when using different -DCPPZMQ_BASE options
unset(HAVE_ZMQ_HPP CACHE)
CHECK_INCLUDE_FILE_CXX(zmq.hpp HAVE_ZMQ_HPP)
if(NOT HAVE_ZMQ_HPP)
    message(FATAL_ERROR "zmq.hpp include file not found. \n
Please install cppzmq (https://github.com/zeromq/cppzmq) on your system and/or use \
-DCPPZMQ_BASE=<cppzmq home folder> option to specify where zmq.hpp file is installed \
(CMake will look for it under <CPPZMQ_BASE>/include, <ZMQ_BASE>/include, \
<OMNI_BASE>/include and system include directories).")
endif()

if(NOT WIN32)
  try_compile(TANGO_ZMQ_HAS_DISCONNECT ${CMAKE_BINARY_DIR}/test_cppzmq_disconnect
              SOURCES ${CMAKE_SOURCE_DIR}/configure/test_cppzmq_disconnect.cpp
              COMPILE_DEFINITIONS "-I ${CPPZMQ_BASE}/include -I ${ZMQ_BASE}/include"
              LINK_LIBRARIES "${ZMQ_PKG_LIBRARIES}")

  message(STATUS "Check if zmq::socket has a disconnect method: ${TANGO_ZMQ_HAS_DISCONNECT}")
else()
  set(TANGO_ZMQ_HAS_DISCONNECT TRUE)
  message(STATUS "Check if zmq::socket has a disconnect method: ${TANGO_ZMQ_HAS_DISCONNECT} (hardcoded)")
endif(NOT WIN32)

message("Verifying ${OMNIIDL_PATH}omniidl")
if(WIN32)
    execute_process(COMMAND ${OMNIIDL_PATH}omniidl.exe -V RESULT_VARIABLE FAILED)
else()
    execute_process(COMMAND ${OMNIIDL_PATH}omniidl -V RESULT_VARIABLE FAILED)
endif()

if(${FAILED})
    message(SEND_ERROR " No omniidl was found! rv=${FAILED}")
endif()

if(NOT WIN32)
    include(CheckCXXCompilerFlag)
    # C++17 and higher support is currently not possible as omniorb uses
    # throw specifications and these are not supported anymore.
    CHECK_CXX_COMPILER_FLAG("-std=c++14" COMPILER_SUPPORTS_CXX14)
    CHECK_CXX_COMPILER_FLAG("-Og" COMPILER_SUPPORTS_OG)
    if(COMPILER_SUPPORTS_CXX14)
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
    endif()

    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
        message("found GNU compiler ...")
        if(CMAKE_BUILD_TYPE STREQUAL "Release")
            message("setup for release build ...")
            add_definitions(-D_FORTIFY_SOURCE=2)
        else()
            message("setup for debug build ...")
            if(COMPILER_SUPPORTS_OG)
                add_compile_options(-Og)
            else()
                add_compile_options(-O0)
            endif()
	    add_compile_options(-Wall -Wextra -pedantic)
        endif()
    endif()
endif()

if(WARNINGS_AS_ERRORS)
  if(WIN32)
    add_compile_options(/WX)
  else()
    add_compile_options(-Werror)
  endif()
endif()

if(cxx_relaxed_constexpr IN_LIST CMAKE_CXX_COMPILE_FEATURES)
  set(TANGO_CXX_HAS_RELAXED_CONSTEXPR TRUE)
else()
  set(TANGO_CXX_HAS_RELAXED_CONSTEXPR FALSE)
endif()

message(STATUS "Check if the compiler supports C++14 relaxed constexpr: ${TANGO_CXX_HAS_RELAXED_CONSTEXPR}")

include(GNUInstallDirs)
include(configure/coveralls.cmake)

option(TANGO_USE_USING_NAMESPACE "Use \"using namespace\" in header files (deprecated, but ON for backwards compatibility.)." ON)
option(TANGO_JPEG_MMX "Build MMX support" ON)
